package vista.paneles;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import logica.Atributo;
import logica.AtributoSimpleException;

@SuppressWarnings("serial")
public class TreeDeAtributos extends JTree {
	
	private static final String PATH_IMAGEN_HOJA = "../imagenes/atributoSimple.png";
	private static final String PATH_IMAGEN_ABIERTO = "../imagenes/atributoCompuesto.png";
	
	private DefaultTreeModel modeloArbol;
	private DefaultMutableTreeNode raiz;
	
	public TreeDeAtributos(DefaultMutableTreeNode raiz)
	{
		super(new DefaultTreeModel(raiz));

		this.modeloArbol = (DefaultTreeModel) this.getModel();
		this.raiz = raiz;

		((DefaultTreeCellRenderer)this.getCellRenderer()).setLeafIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_HOJA)));
		((DefaultTreeCellRenderer)this.getCellRenderer()).setOpenIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_ABIERTO)));
		((DefaultTreeCellRenderer)this.getCellRenderer()).setClosedIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_ABIERTO)));

		this.setRootVisible(false);
		this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		
	    TreePath parentPath = this.getSelectionPath();
	    this.expandPath(parentPath);
	}
	
	public void agregarAtributo(Atributo atributo)
	{
		this.agregarAtributoAlArbol(atributo, raiz);
	}
	
	public void agregarAtributosAlArbol(List<Atributo> atributos)
	{
		Iterator<Atributo> atributo = atributos.iterator();
		
		while(atributo.hasNext())
			this.agregarAtributo(atributo.next());
	}
	
	private void agregarAtributoAlArbol(Atributo atributo, DefaultMutableTreeNode nodoPadre)
	{
		DefaultMutableTreeNode nodoHijo = new DefaultMutableTreeNode(atributo);

        this.modeloArbol.insertNodeInto(nodoHijo, nodoPadre, nodoPadre.getChildCount());
        this.expandPath(new TreePath(nodoPadre));
        
		try 
		{
			 Iterator<Atributo> iterador = atributo.getAtributos().iterator();
		      while (iterador.hasNext())
		      {
		    	  this.agregarAtributoAlArbol(iterador.next(), nodoHijo);
		      }
		      
		} catch (AtributoSimpleException e) {}
	}
	
	public void quitarAtributo() throws NoEsNodoPadre
	{	
		TreePath currentSelection =  this.getSelectionPath();
			    
		if (currentSelection != null)
		{
			DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
			
			if (currentNode.getLevel() != 1)
				throw new NoEsNodoPadre("No se puede borrar un Atributo contenido dentro de uno compuesto.");
			
			MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
			
			if (parent != null)
			{
				modeloArbol.removeNodeFromParent(currentNode);
				return;
			}
		}
	}
	
	public void editarAtributo(Atributo atributoEditado)
	{
		TreePath currentSelection =  this.getSelectionPath();

		if (currentSelection != null)
		{
			DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
			MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
			
			if (parent != null)
			{
				TreePath padrePath =  this.getSelectionPath().getParentPath();
				DefaultMutableTreeNode nodoPadre = (DefaultMutableTreeNode)(padrePath.getLastPathComponent());

				modeloArbol.removeNodeFromParent(currentNode);
				
				agregarAtributoAlArbol(atributoEditado, nodoPadre);
				return;
			}
		}
		
	}
	
	public Atributo getAtributoSeleccionado()
	{	
		TreePath currentSelection =  this.getSelectionPath();
			    
		if (currentSelection != null)
		{
			DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
			
			return (Atributo)currentNode.getUserObject();
		}
		
		return null;
	}
	
	public List<Atributo> getAtributos()
	{
		List<Atributo> objetos = new LinkedList<Atributo>();
		
		int nroElemento = 0;
		while (nroElemento < this.modeloArbol.getChildCount(raiz))
		{
			DefaultMutableTreeNode nodo = (DefaultMutableTreeNode)this.modeloArbol.getChild(raiz, nroElemento); 
			objetos.add((Atributo)nodo.getUserObject());
			nroElemento++;
		}
		
		return objetos;
	}

}
